
using System;
using System.Collections.Generic;
using System.Text;
using ttg_internal.utils;

namespace SampleUtility
{
    /// <summary>
    /// Prints information from GlobalInfo (using readable format).
    /// </summary>
    internal static class GlobalInfoPrinter
    {
        /// <summary>
        /// Prints single parameter.
        /// </summary>
        private static void AddParameter(StringBuilder buffer, String offset, Parameter parameter)
        {
            //Printing value.
            buffer.Append(offset);
            buffer.Append(parameter.Name);
            buffer.Append(" = ");
            buffer.Append(parameter.Value);
            //Printing type info.
            buffer.Append(" (");
            buffer.Append(parameter.Info.Type.ToString());
            //Printing range for int.
            if (parameter.Info.Type == ParameterType.Int64)
            {
                ParameterInfo_Int64 info = (ParameterInfo_Int64)parameter.Info;
                if (info.HasBounds)
                {
                    buffer.Append("[");
                    buffer.Append(info.LowBound.ToString());
                    buffer.Append(",");
                    buffer.Append(info.HighBound.ToString());
                    buffer.Append("]");
                }

            }
            //Printing range for double.
            if (parameter.Info.Type == ParameterType.Double)
            {
                ParameterInfo_Double info = (ParameterInfo_Double)parameter.Info;
                if (info.HasBounds)
                {
                    buffer.Append("[");
                    buffer.Append(info.LowBound.ToString());
                    buffer.Append(",");
                    buffer.Append(info.HighBound.ToString());
                    buffer.Append("]");
                }

            }
            //Printing enumeration elements.
            if (parameter.Info.Type == ParameterType.Enum)
            {
                ParameterInfo_Enum info = (ParameterInfo_Enum)parameter.Info;
                buffer.Append("{");
                buffer.Append(String.Join(",", new List<String>(info.Elements).ToArray()));
                buffer.Append("}");
            }
            //Finishing.
            buffer.Append(")");
            buffer.Append(Environment.NewLine);
        }
        /// <summary>
        /// Prints set of parameters.
        /// </summary>
        private static void AddParameters(StringBuilder buffer, String offset, ParameterSet parameters)
        {
            if (parameters != null)
            {
                buffer.Append(offset);
                buffer.Append(parameters.Name);
                buffer.Append(":");
                buffer.Append(Environment.NewLine);
                offset += "    ";
                foreach (ParameterSet ps in parameters.SubSets)
                    AddParameters(buffer, offset, ps);
                foreach (Parameter p in parameters.Parameters)
                    AddParameter(buffer, offset, p);
            }
        }
        private static void AddNode(StringBuilder buffer, String offset, Node node)
        {
            buffer.Append(offset + node.Name + Environment.NewLine);
            buffer.Append(offset + "    ActiveTaskCount = " + node.ActiveTaskCount + Environment.NewLine);
            buffer.Append(offset + "    Usage = " + node.Usage + Environment.NewLine);
            buffer.Append(offset + "    Outputs:" + Environment.NewLine);
            foreach (Node nd in node.Outputs)
            {
                buffer.Append(offset + "        " + nd.Name + Environment.NewLine);
            }
        }
        private static void AddPipeline(StringBuilder buffer, String offset, Pipeline pipeline)
        {
            buffer.Append(offset + pipeline.Name + Environment.NewLine);
            foreach (Node nd in pipeline.Nodes)
            {
                AddNode(buffer, offset + "    ", nd);
            }
        }
        /// <summary>
        /// Adds information about pipelines.
        /// </summary>
        private static void AddPipelines(StringBuilder buffer, String offset, PipelineSet pipelines)
        {
            buffer.Append(offset + "Pipelines:" + Environment.NewLine);
            foreach (Pipeline pl in pipelines.Pipelines)
            {
                AddPipeline(buffer, offset + "    ", pl);
            }
        }
        public static String PrintInfo(GlobalInfo info)
        {
            StringBuilder res = new StringBuilder();
            //Adding devices.
            info.Lock();
            foreach (DeviceInfo device in info.Devices)
            {
                res.Append(device.Name);
                res.Append(":" + Environment.NewLine);
                foreach (SubSystemInfo ssystem in device.SubSystems)
                {
                    res.Append("    ");
                    res.Append(ssystem.ToString());
                    res.Append(Environment.NewLine);
                }
            }
            info.UnLock();
            //Adding pipelines.
            AddPipelines(res, "", info.Pipelines);
            //Adding parameters.
            info.Parameters.Lock();
            AddParameters(res, "", info.Parameters.Root);
            info.Parameters.UnLock();
            return res.ToString();
        }
    }
}
